package auctionhaus

/**
 * Created by IntelliJ IDEA.
 * User: Chris Seeling
 * Date: 2/9/12
 * Time: 8:04 PM
 * To change this template use File | Settings | File Templates.
 */
class DomainIntegrationTests extends GroovyTestCase {

    void testCustomerEmail() {
        def existingCustomer = new Customer(
                email: "johndoe@acme.com",
                password: "1234567"
        )
        existingCustomer.save(flush: true)

        String badEmailString = "johndoeatacme.com"
        //test malformed email
        def badEmailCustomer = new Customer(
                email: badEmailString,
                password: "123457"
        )
        badEmailCustomer.save(flush: true)
        assertNull Customer.findByEmail(badEmailString)

        //test non-unique email
        String nonUniqueString = "johndoe@acme.com"
        def duplicateCustomer = new Customer(
                email: nonUniqueString,
                password: "1122334"
        )
        duplicateCustomer.save(flush: true)
        def customers = Customer.findAllByEmail(nonUniqueString)
        assert customers.size() == 1

        //test a regular email
        String normalEmail = "jane.doe@acme.com"
        def normalCustomer = new Customer(
                email: normalEmail,
                password: "asdfgh"
        )
        normalCustomer.save(flush: true)
        assertNotNull Customer.findByEmail(normalEmail)
    }

    void testListingBidRelationship() {
        String email = "johndoe@acme.com"
        def seller = new Customer(
                email: email,
                password: "1234567"
        )
        seller.save(flush: true)
        assertNotNull Customer.findByEmail(email)

        def firstBid = new Bid(
                amount: 1,
                bidder: seller,
        )
        firstBid.save(flush: true)
        assertNotNull Bid.findById(firstBid.id)

        def listing = new Listing(
                name: "My awesome pocket lint!",
                endTime: new Date() + 5,
                seller: seller,
                startBid: 1,
                bids: [firstBid]
        )
        listing.save(flush: true)
        assertNotNull Listing.findBySeller(seller)

        def newCustomer = new Customer(
                email: "jane.doe@acme.com",
                password: "1234567"
        )
        newCustomer.save(flush: true)

        def newBid = new Bid(
                amount: 2,
                bidder: newCustomer
        )

        listing.addToBids(newBid)
        listing.save(flush: true)
        
        assertNotNull Bid.findById(newBid.id)
    }

    void testBidThreshold() {
        String email = "johndoe@acme.com"
        def seller = new Customer(
                email: email,
                password: "1234567"
        )
        seller.save(flush: true)
        assertNotNull Customer.findByEmail(email)

        def firstBid = new Bid(
                amount: 1,
                bidder: seller,
        )
        firstBid.save(flush: true)
        assertNotNull Bid.findById(firstBid.id)

        def listing = new Listing(
                name: "My awesome pocket lint!",
                endTime: new Date() + 5,
                seller: seller,
                startBid: 1,
                bids: [firstBid]
        )
        listing.save(flush: true)
        assertNotNull Listing.findBySeller(seller)

        def newCustomer = new Customer(
                email: "jane.doe@acme.com",
                password: "1234567"
        )
        newCustomer.save(flush: true)

        def underBid = new Bid(
                amount: 1.1,
                bidder: newCustomer
        )

        listing.addToBids(underBid)
        assertFalse listing.validate()
        listing.save(flush: true)
        assertNull underBid.id

        listing.bids.clear()
        listing.addToBids(firstBid)

        def badBid = new Bid()
        assertFalse badBid.validate()
        listing.addToBids(badBid)
        listing.save(flush: true)
        assertNull badBid.id

        listing.bids.clear()
        listing.addToBids(firstBid)

        def aboveBid = new Bid(
                amount: 1.5,
                bidder: newCustomer
        )

        listing.addToBids(aboveBid)
        listing.save(flush: true)
        assertNotNull Bid.findById(aboveBid.id)
    }

    // test deleting customer with and without bids
    void testDeleteCustomerWithBids() {
        // create a customer
        String email = "customer1@acme.com"
        Customer firstCustomer = new Customer(
                email: email,
                password: "1234567"
        )
        firstCustomer.save(flush: true)

        // verify that customer exists
        assertNotNull Customer.findByEmail(email)

        // try to delete customer (it should succeed because they have no bids)
        try {
            firstCustomer.delete(flush: true)
        }
        catch(e){
            assert false // we should not get here because the delete should succeed
        }

        // verify that customer does NOT exist
        assertNull Customer.findByEmail(email)

        // create another customer
        String email2 = "customer2@acme.com"
        Customer secondCustomer = new Customer(
                email: email2,
                password: "1234567"
        )
        secondCustomer.save(flush: true)

        // verify that customer exists
        assertNotNull Customer.findByEmail(email2)

        // create a bid for the customer
        def secondCustomerBid = new Bid(
                amount: 1,
                bidder: secondCustomer,
        )
        secondCustomerBid.save(flush: true)

        // verify that bid exists
        assertNotNull Bid.findById(secondCustomerBid.id)

        // try to delete customer (it should fail because they have a bid)
        try {
            secondCustomer.delete(flush: true)
            assert false // we should not get here because the delete should fail
        }
        catch(e){
            assert true // we should get here because the delete now fails since the customer has a bid
        }
    }

    // test deleting customer with and without listings
    void testDeleteCustomerWithListings() {
        // create a customer
        String email = "customer1@acme.com"
        Customer firstCustomer = new Customer(
                email: email,
                password: "1234567"
        )
        firstCustomer.save(flush: true)

        // verify that customer exists
        assertNotNull Customer.findByEmail(email)

        // try to delete customer (it should succeed because they have no bids)
        try {
            firstCustomer.delete(flush: true)
        }
        catch(e){
            assert false // we should not get here because the delete should succeed
        }

        // verify that customer does NOT exist
        assertNull Customer.findByEmail(email)

        // create another customer
        String email2 = "customer2@acme.com"
        Customer secondCustomer = new Customer(
                email: email2,
                password: "1234567"
        )
        secondCustomer.save(flush: true)

        // verify that customer exists
        assertNotNull Customer.findByEmail(email2)

        // create a bid for the customer
        Bid secondCustomerBid = new Bid(
                amount: 1,
                bidder: secondCustomer,
        )
        secondCustomerBid.save(flush: true)

        // verify that bid exists
        assertNotNull Bid.findById(secondCustomerBid.id)

        Listing listing = new Listing(
                name: "My awesome pocket lint!",
                endTime: new Date() + 5,
                seller: secondCustomer,
                startBid: 1,
                bids: [secondCustomerBid]
        )
        listing.save(flush: true)
        assertNotNull Listing.findBySeller(secondCustomer)

        // try to delete customer (it should fail because they have a listing)
        try {
            secondCustomer.delete(flush: true)
            assert false // we should not get here because the delete should fail
        }
        catch(e){
            assert true // we should get here because the delete now fails since the customer has a listing
        }
    }
}
